package com.cskaoyan.javase.array._7call;

import java.util.Arrays;

/**
 * 方法的传参/传值问题
 * 什么是方法的传值问题？
 * 调用方法时，我们需要传递实参给方法，在方法内部有可能会改变这些实参的值。
 * 那么方法执行完毕后，这些实参的值在原先的方法中会怎么改变呢？
 * 这就是方法的传值问题。
 *
 * 两个概念/两种方法传值的方式:
 * 1.值传递（call by value）指的是调用方法时,传入的是实参的拷贝而不是实参本身。
 * 如果Java是值传递的,那么方法改变的是实参拷贝的值,原本实参的值是不会被改变的。
 *
 * 2.引用传递（call by reference）指的是调用方法时,传入的是实参变量的地址,也就是实参本身。
 * 如果Java是引用传递的,方法改变的是实参本身的值,方法结束后,原本实参变量的值会随之改变。
 *
 *
 * 接下来进行代码测试
 *
 * -----------------------------------------------------------
 * 我们通过一个将基本数据类型实参变量变为原先二倍的方法,调用这个方法,发现没有修改实参变量取值成功
 * 这说明:
 *      至少对于基本数据类型而言,Java的传值方式是值传递的,因为Java方法不能修改实参变量的取值!
 *
 * 我们通过一个将引用数据类型数组元素变为原先二倍的方法,调用这个方法,发现修改数组元素成功了
 * 这说明:
 *      至少对于引用数据类型而言,Java的传值方式是引用传递的,因为Java方法能修改实参变量的取值!
 * -----------------------------------------------------------
 *
 * 以上分割线中的结论是典型的关于Java传值方式的错误结论,实际上java只有值传递!! Java没有任何引用传递!!
 *
 *
 * 总结,我们知道Java是值传递后,我们要知道:
 * Java的方法究竟能够对传入方法的实参做什么呢?
 *      1.Java的方法是不能修改另外一个方法内部的局部变量的,因为Java方法的局部变量仅在方法内部生效
 *          扩展来说就是:
 *          方法不能修改基本数据类型实参变量的取值
 *          方法不能修改引用数据类型实参变量的引用,不能去修改实参的引用
 *
 *      2.Java方法可以改变对象的状态(原因是引用的拷贝和引用本身仍然指向同一个对象)
 *
 *
 *
 * @since 09:58
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        int a = 10;
        doubleIntValue(a);
        System.out.println(a);
        System.out.println("---------------------");
        int[] arr = {1, 2, 3};
        System.out.println("调用方法之前:" + Arrays.toString(arr));
        doubleIntArrElement(arr);
        System.out.println("调用方法之后:" + Arrays.toString(arr));
        System.out.println("---------------------");
        int[] arr1 = {666, 666, 666};
        int[] arr2 = {777, 777, 777};
        System.out.println("交换之前arr1:" + Arrays.toString(arr1));
        System.out.println("交换之前arr2:" + Arrays.toString(arr2));
        swapIntArr(arr1, arr2);
        System.out.println("交换之后arr1:" + Arrays.toString(arr1));
        System.out.println("交换之后arr2:" + Arrays.toString(arr2));
    }

    /*
        把一个基本类型实参变为原先的二倍
     */
    public static void doubleIntValue(int a) {
        a *= 2;
    }

    /*
        把一个引用数据类型数组的元素取值变为原先的二倍
     */
    public static void doubleIntArrElement(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            arr[i] *= 2;
        }
    }


    /*
        交换两个int类型数组的引用
     */
    public static void swapIntArr(int[] arr1, int[] arr2) {
        int[] temp = arr1;
        arr1 = arr2;
        arr2 = temp;
    }
}
